import { Context } from 'koa'
import response from '../../utils/response'
import { MethodName } from '../router/decorator/type'
import {
  get,
  post,
  patch,
  controller,
  use,
  unifyUse
} from '../router/decorator/index'
import AdminService from '../service/AdminService'
import {
  adminValidator,
  crpytPassword,
  verifyAdmin,
  verifyLogin
} from '../middleware/AdminMiddleware'
import config from '../config'
import jwt from 'jsonwebtoken'
import {
  GetAdminException,
  PasswordValidationException,
  UserValidationException
} from '../exception/HttpException'
import { authToken } from '../middleware/AuthMiddleware'
import bcrypt from 'bcryptjs'

//管理员管理控制器
@controller('/admin')
@unifyUse<MethodName>(adminValidator, ['changePassword', 'getUserInfoById'])
class AdminController {
  //用户注册接口
  @post('/register')
  @use(crpytPassword)
  @use(verifyAdmin)
  async register(ctx: Context) {
    const { username, password } = ctx.request.body
    console.log(username, password)
    try {
      const res = await AdminService.createAdmin(username, password)
      response.success(ctx, res, '用户注册成功！')
    } catch (err) {
      console.log(err)
    }
  }

  //用户登录接口
  @post('/login')
  @use(verifyLogin)
  async login(ctx: Context) {
    const { username } = ctx.request.body
    //1.获取用户信息
    try {
      const result = await AdminService.getAdminInfo({ username })
      //从返回结果对象中剔除password属性，将剩下的属性放到新的对象中
      const { password, ...res } = result

      const JWT_SECRET = config.jwt.jwt_secret
      //拼接token
      let token = jwt.sign(res, JWT_SECRET as string, { expiresIn: '2.5h' })
      //{token} 相当于{ token: token }
      response.success(ctx, { token }, '用户登录成功！')
    } catch (err) {
      throw new UserValidationException(err, '用户登录失败！', 400)
    }
  }

  //修改密码接口
  @patch('/')
  @use(crpytPassword)
  @use(authToken)
  async changePassword(ctx: Context) {
    // 1.获取数据
    //  id为state的数据，因为在解析token时，user数据被写在ctx.state中
    const id = ctx.state.user.id
    console.log(id)
    // newpassword为
    const password = ctx.request.body.password
    const username = ctx.state.user.username
    console.log(password, '要修改的密码！')
    //2.操作数据库
    try {
      const res1 = await AdminService.getAdminInfo({ username })

      console.log(res1.password, '数据库中的密码')

      if (!res1) {
        return response.failResponse(ctx, '用户不存在！', username)
      }

      if (bcrypt.compareSync(password, res1.password)) {
        throw new PasswordValidationException('', '新密码和旧密码相同！')
      }

      const res2 = await AdminService.updateById({ id, username, password })

      if (res2) {
        response.success(ctx, res2, '密码修改成功！')
      }
    } catch (err) {
      throw new PasswordValidationException(err, '密码修改失败！')
    }

    // try {
    //   const res = await getUserInfo({ username })
    //   if (bcrypt.compareSync(newPassword, res.password)) {
    //     ctx.app.emit('error', samePassword, ctx)
    //     return
    //   }

    //   //加盐
    //   const salt = bcrypt.genSaltSync(10)
    //   //hash保存的是密文
    //   const hash = bcrypt.hashSync(newPassword, salt)
    //   const password = hash

    //   //2.操作数据库
    //   if (await updateById({ id, password })) {
    //     ctx.body = {
    //       code: 0,
    //       message: '修改密码成功！',
    //       data: ''
    //     }
    //   }
    // } catch (err) {
    //   console.log('修改密码失败')
    //   ctx.app.emit('error', changePassword, ctx)
    // }
  }

  //获取用户信息接口
  @get('/user')
  @use(authToken)
  async getUserInfoById(ctx: Context) {
    try {
      const { id } = ctx.state.user
      //把字符串类型转换为数字类型
      let userId = Number(id)
      console.log(userId, 'userId')
      const res = await AdminService.findUserInfoById(userId)
      response.success(ctx, res, '通过ID获取用户信息成功！')
    } catch (error: any) {
      throw new GetAdminException(error, error.messages)
    }
  }
}

export default new AdminController()
